package parser

import (
	"fmt"
	"strings"
)

// SQLGenerator 负责将AST节点转换为SQL字符串
type SQLGenerator struct {
	indentLevel int
	useIndent   bool
}

// NewSQLGenerator 创建一个新的SQL生成器
func NewSQLGenerator(useIndent bool) *SQLGenerator {
	return &SQLGenerator{
		indentLevel: 0,
		useIndent:   useIndent,
	}
}

// Generate 生成SQL字符串
func (g *SQLGenerator) Generate(node Node) string {
	switch n := node.(type) {
	case *SelectStmt:
		return g.generateSelectStmt(n)
	case *InsertStmt:
		return g.generateInsertStmt(n)
	case *UpdateStmt:
		return g.generateUpdateStmt(n)
	case *DeleteStmt:
		return g.generateDeleteStmt(n)
	case *CreateTableStmt:
		return g.generateCreateTableStmt(n)
	case *DropTableStmt:
		return g.generateDropTableStmt(n)
	case *CreateIndexStmt:
		return g.generateCreateIndexStmt(n)
	case *DropIndexStmt:
		return g.generateDropIndexStmt(n)
	case *CreateViewStmt:
		return g.generateCreateViewStmt(n)
	case *DropViewStmt:
		return g.generateDropViewStmt(n)
	case *AlterTableStmt:
		return g.generateAlterTableStmt(n)
	case *BeginStmt:
		return g.generateBeginStmt(n)
	case *CommitStmt:
		return g.generateCommitStmt(n)
	case *RollbackStmt:
		return g.generateRollbackStmt(n)
	case *SavepointStmt:
		return g.generateSavepointStmt(n)
	case *ReleaseSavepointStmt:
		return g.generateReleaseSavepointStmt(n)
	case *GrantStmt:
		return g.generateGrantStmt(n)
	case *RevokeStmt:
		return g.generateRevokeStmt(n)
	default:
		return fmt.Sprintf("/* Unsupported node type: %T */", node)
	}
}

// generateSelectStmt 生成SELECT语句
func (g *SQLGenerator) generateSelectStmt(stmt *SelectStmt) string {
	var parts []string

	// SELECT子句
	selectClause := "SELECT"
	if stmt.Distinct {
		selectClause += " DISTINCT"
	}

	// 目标列表
	if len(stmt.Targets) > 0 {
		targets := make([]string, len(stmt.Targets))
		for i, target := range stmt.Targets {
			targets[i] = g.generateExpression(target)
		}
		selectClause += " " + strings.Join(targets, ", ")
	} else {
		selectClause += " *"
	}
	parts = append(parts, selectClause)

	// FROM子句
	if len(stmt.From) > 0 {
		fromTables := make([]string, len(stmt.From))
		for i, table := range stmt.From {
			fromTables[i] = g.generateTableRef(table)
		}
		parts = append(parts, "FROM "+strings.Join(fromTables, ", "))
	}

	// WHERE子句
	if stmt.Where != nil {
		parts = append(parts, "WHERE "+g.generateExpression(stmt.Where))
	}

	// GROUP BY子句
	if len(stmt.GroupBy) > 0 {
		groupByExprs := make([]string, len(stmt.GroupBy))
		for i, expr := range stmt.GroupBy {
			groupByExprs[i] = g.generateExpression(expr)
		}
		parts = append(parts, "GROUP BY "+strings.Join(groupByExprs, ", "))
	}

	// HAVING子句
	if stmt.Having != nil {
		parts = append(parts, "HAVING "+g.generateExpression(stmt.Having))
	}

	// ORDER BY子句
	if len(stmt.OrderBy) > 0 {
		orderByExprs := make([]string, len(stmt.OrderBy))
		for i, expr := range stmt.OrderBy {
			orderByExprs[i] = g.generateOrderByExpr(&expr)
		}
		parts = append(parts, "ORDER BY "+strings.Join(orderByExprs, ", "))
	}

	// LIMIT子句
	if stmt.Limit != nil {
		parts = append(parts, "LIMIT "+g.generateExpression(stmt.Limit))
	}

	// OFFSET子句
	if stmt.Offset != nil {
		parts = append(parts, "OFFSET "+g.generateExpression(stmt.Offset))
	}

	if g.useIndent {
		return strings.Join(parts, "\n")
	}
	return strings.Join(parts, " ")
}

// generateInsertStmt 生成INSERT语句
func (g *SQLGenerator) generateInsertStmt(stmt *InsertStmt) string {
	var parts []string

	parts = append(parts, "INSERT INTO "+g.generateTableRef(*stmt.Table))

	// 列名列表
	if len(stmt.Columns) > 0 {
		parts[len(parts)-1] += " (" + strings.Join(stmt.Columns, ", ") + ")"
	}

	// VALUES子句或SELECT子句
	if stmt.Select != nil {
		parts = append(parts, g.generateSelectStmt(stmt.Select))
	} else if len(stmt.Values) > 0 {
		valuesList := make([]string, len(stmt.Values))
		for i, values := range stmt.Values {
			valueExprs := make([]string, len(values))
			for j, value := range values {
				valueExprs[j] = g.generateExpression(value)
			}
			valuesList[i] = "(" + strings.Join(valueExprs, ", ") + ")"
		}
		parts = append(parts, "VALUES "+strings.Join(valuesList, ", "))
	}

	if g.useIndent {
		return strings.Join(parts, "\n")
	}
	return strings.Join(parts, " ")
}

// generateUpdateStmt 生成UPDATE语句
func (g *SQLGenerator) generateUpdateStmt(stmt *UpdateStmt) string {
	var parts []string

	parts = append(parts, "UPDATE "+g.generateTableRef(*stmt.Table))

	// SET子句
	if len(stmt.Set) > 0 {
		setExprs := make([]string, len(stmt.Set))
		for i, setExpr := range stmt.Set {
			setExprs[i] = g.generateUpdateExpr(&setExpr)
		}
		parts = append(parts, "SET "+strings.Join(setExprs, ", "))
	}

	// WHERE子句
	if stmt.Where != nil {
		parts = append(parts, "WHERE "+g.generateExpression(stmt.Where))
	}

	if g.useIndent {
		return strings.Join(parts, "\n")
	}
	return strings.Join(parts, " ")
}

// generateDeleteStmt 生成DELETE语句
func (g *SQLGenerator) generateDeleteStmt(stmt *DeleteStmt) string {
	var parts []string

	parts = append(parts, "DELETE FROM "+g.generateTableRef(*stmt.Table))

	// WHERE子句
	if stmt.Where != nil {
		parts = append(parts, "WHERE "+g.generateExpression(stmt.Where))
	}

	if g.useIndent {
		return strings.Join(parts, "\n")
	}
	return strings.Join(parts, " ")
}

// generateCreateTableStmt 生成CREATE TABLE语句
func (g *SQLGenerator) generateCreateTableStmt(stmt *CreateTableStmt) string {
	var parts []string

	createClause := "CREATE"
	if stmt.Temporary {
		createClause += " TEMPORARY"
	}
	if stmt.Unlogged {
		createClause += " UNLOGGED"
	}
	createClause += " TABLE"
	if stmt.IfNotExists {
		createClause += " IF NOT EXISTS"
	}
	createClause += " " + g.generateTableRef(*stmt.Table)

	parts = append(parts, createClause)

	// 列定义
	if len(stmt.Columns) > 0 {
		columnDefs := make([]string, len(stmt.Columns))
		for i, col := range stmt.Columns {
			columnDefs[i] = g.generateColumnDef(col)
		}
		parts = append(parts, "("+strings.Join(columnDefs, ", ")+")")
	}

	return strings.Join(parts, " ")
}

// generateDropTableStmt 生成DROP TABLE语句
func (g *SQLGenerator) generateDropTableStmt(stmt *DropTableStmt) string {
	dropClause := "DROP TABLE"
	if stmt.IfExists {
		dropClause += " IF EXISTS"
	}

	tableNames := make([]string, len(stmt.Tables))
	for i, table := range stmt.Tables {
		tableNames[i] = g.generateTableRef(*table)
	}
	dropClause += " " + strings.Join(tableNames, ", ")

	if stmt.Cascade {
		dropClause += " CASCADE"
	}

	return dropClause
}

// generateCreateIndexStmt 生成CREATE INDEX语句
func (g *SQLGenerator) generateCreateIndexStmt(stmt *CreateIndexStmt) string {
	createClause := "CREATE"
	if stmt.Unique {
		createClause += " UNIQUE"
	}
	createClause += " INDEX"
	if stmt.Concurrent {
		createClause += " CONCURRENTLY"
	}
	if stmt.IfNotExists {
		createClause += " IF NOT EXISTS"
	}
	if stmt.Name != "" {
		createClause += " " + stmt.Name
	}
	createClause += " ON " + g.generateTableRef(*stmt.Table)

	// 索引列
	if len(stmt.Columns) > 0 {
		columnExprs := make([]string, len(stmt.Columns))
		for i, col := range stmt.Columns {
			columnExprs[i] = g.generateIndexColumn(col)
		}
		createClause += " (" + strings.Join(columnExprs, ", ") + ")"
	}

	return createClause
}

// generateDropIndexStmt 生成DROP INDEX语句
func (g *SQLGenerator) generateDropIndexStmt(stmt *DropIndexStmt) string {
	dropClause := "DROP INDEX"
	if stmt.Concurrent {
		dropClause += " CONCURRENTLY"
	}
	if stmt.IfExists {
		dropClause += " IF EXISTS"
	}
	dropClause += " " + strings.Join(stmt.Indexes, ", ")

	if stmt.Cascade {
		dropClause += " CASCADE"
	}

	return dropClause
}

// generateCreateViewStmt 生成CREATE VIEW语句
func (g *SQLGenerator) generateCreateViewStmt(stmt *CreateViewStmt) string {
	createClause := "CREATE"
	if stmt.Replace {
		createClause += " OR REPLACE"
	}
	if stmt.Temporary {
		createClause += " TEMPORARY"
	}
	if stmt.Recursive {
		createClause += " RECURSIVE"
	}
	createClause += " VIEW " + g.generateTableRef(*stmt.Name)

	// 列名列表
	if len(stmt.Columns) > 0 {
		createClause += " (" + strings.Join(stmt.Columns, ", ") + ")"
	}

	createClause += " AS " + g.generateSelectStmt(stmt.Select)

	return createClause
}

// generateDropViewStmt 生成DROP VIEW语句
func (g *SQLGenerator) generateDropViewStmt(stmt *DropViewStmt) string {
	dropClause := "DROP VIEW"
	if stmt.IfExists {
		dropClause += " IF EXISTS"
	}

	viewNames := make([]string, len(stmt.Views))
	for i, view := range stmt.Views {
		viewNames[i] = g.generateTableRef(*view)
	}
	dropClause += " " + strings.Join(viewNames, ", ")

	if stmt.Cascade {
		dropClause += " CASCADE"
	}

	return dropClause
}

// generateAlterTableStmt 生成ALTER TABLE语句
func (g *SQLGenerator) generateAlterTableStmt(stmt *AlterTableStmt) string {
	alterClause := "ALTER TABLE " + g.generateTableRef(*stmt.Table)

	if len(stmt.Actions) > 0 {
		actionStrs := make([]string, len(stmt.Actions))
		for i, action := range stmt.Actions {
			actionStrs[i] = g.generateAlterTableAction(action)
		}
		alterClause += " " + strings.Join(actionStrs, ", ")
	}

	return alterClause
}

// generateBeginStmt 生成BEGIN语句
func (g *SQLGenerator) generateBeginStmt(stmt *BeginStmt) string {
	return "BEGIN"
}

// generateCommitStmt 生成COMMIT语句
func (g *SQLGenerator) generateCommitStmt(stmt *CommitStmt) string {
	commitClause := "COMMIT"
	if stmt.Chain {
		commitClause += " AND CHAIN"
	}
	return commitClause
}

// generateRollbackStmt 生成ROLLBACK语句
func (g *SQLGenerator) generateRollbackStmt(stmt *RollbackStmt) string {
	rollbackClause := "ROLLBACK"
	if stmt.Savepoint != "" {
		rollbackClause += " TO " + stmt.Savepoint
	}
	if stmt.Chain {
		rollbackClause += " AND CHAIN"
	}
	return rollbackClause
}

// generateSavepointStmt 生成SAVEPOINT语句
func (g *SQLGenerator) generateSavepointStmt(stmt *SavepointStmt) string {
	return "SAVEPOINT " + stmt.Name
}

// generateReleaseSavepointStmt 生成RELEASE SAVEPOINT语句
func (g *SQLGenerator) generateReleaseSavepointStmt(stmt *ReleaseSavepointStmt) string {
	return "RELEASE SAVEPOINT " + stmt.Name
}

// generateGrantStmt 生成GRANT语句
func (g *SQLGenerator) generateGrantStmt(stmt *GrantStmt) string {
	return "GRANT /* privileges */ ON /* objects */ TO /* grantees */"
}

// generateRevokeStmt 生成REVOKE语句
func (g *SQLGenerator) generateRevokeStmt(stmt *RevokeStmt) string {
	return "REVOKE /* privileges */ ON /* objects */ FROM /* grantees */"
}

// 辅助方法：生成表达式
func (g *SQLGenerator) generateExpression(expr Expression) string {
	if expr == nil {
		return ""
	}

	switch e := expr.(type) {
	case *ColumnRef:
		return g.generateColumnRef(e)
	case *Literal:
		return g.generateLiteral(e)
	case *BinaryExpr:
		return g.generateBinaryExpr(e)
	case *UnaryExpr:
		return g.generateUnaryExpr(e)
	case *FunctionCall:
		return g.generateFunctionCall(e)
	case *AggregateExpr:
		return g.generateAggregateExpr(e)
	case *SubqueryExpr:
		return "(" + g.generateSelectStmt(e.Select) + ")"
	case *ExistsExpr:
		return g.generateExistsExpr(e)
	case *InExpr:
		return g.generateInExpr(e)
	case *BetweenExpr:
		return g.generateBetweenExpr(e)
	case *TypeCastExpr:
		return g.generateTypeCastExpr(e)
	case *IsNullExpr:
		return g.generateIsNullExpr(e)
	case *LikeExpr:
		return g.generateLikeExpr(e)
	case *CaseExpr:
		return g.generateCaseExpr(e)
	case *RowExpr:
		return g.generateRowExpr(e)
	case *ArrayExpr:
		return g.generateArrayExpr(e)
	case *ArrayAccess:
		return g.generateArrayAccess(e)
	case *ArraySliceExpr:
		return g.generateArraySliceExpr(e)
	case *CoalesceExpr:
		return g.generateCoalesceExpr(e)
	case *NullIfExpr:
		return g.generateNullIfExpr(e)
	case *GreatestExpr:
		return g.generateGreatestExpr(e)
	case *LeastExpr:
		return g.generateLeastExpr(e)
	case *JSONBExpr:
		return g.generateJSONBExpr(e)
	default:
		return fmt.Sprintf("/* Unsupported expression type: %T */", expr)
	}
}

// generateTableRef 生成表引用
func (g *SQLGenerator) generateTableRef(table TableRef) string {
	result := table.Name
	if table.Alias != "" {
		result += " AS " + table.Alias
	}

	// 处理JOIN
	for _, join := range table.Joins {
		result += " " + g.generateJoinExpr(&join)
	}

	return result
}

// generateColumnRef 生成列引用
func (g *SQLGenerator) generateColumnRef(col *ColumnRef) string {
	if col.Table != "" {
		return col.Table + "." + col.Column
	}
	return col.Column
}

// generateLiteral 生成字面量
func (g *SQLGenerator) generateLiteral(lit *Literal) string {
	switch lit.Type {
	case StringLiteral:
		return fmt.Sprintf("'%v'", lit.Value)
	case IntegerLiteral, FloatLiteral:
		return fmt.Sprintf("%v", lit.Value)
	case BooleanLiteral:
		if lit.Value.(bool) {
			return "TRUE"
		}
		return "FALSE"
	case NullLiteral:
		return "NULL"
	default:
		return fmt.Sprintf("%v", lit.Value)
	}
}

// generateBinaryExpr 生成二元表达式
func (g *SQLGenerator) generateBinaryExpr(expr *BinaryExpr) string {
	left := g.generateExpression(expr.Left)
	right := g.generateExpression(expr.Right)
	op := g.getBinaryOpString(expr.Operator)
	return fmt.Sprintf("(%s %s %s)", left, op, right)
}

// getBinaryOpString 获取二元操作符字符串
func (g *SQLGenerator) getBinaryOpString(op BinaryOp) string {
	switch op {
	case EQ:
		return "="
	case NE:
		return "<>"
	case LT:
		return "<"
	case LE:
		return "<="
	case GT:
		return ">"
	case GE:
		return ">="
	case AND:
		return "AND"
	case OR:
		return "OR"
	case PLUS:
		return "+"
	case MINUS:
		return "-"
	case MULTIPLY:
		return "*"
	case DIVIDE:
		return "/"
	case MODULO:
		return "%"
	case CONCAT:
		return "||"
	case LIKE:
		return "LIKE"
	case ILIKE:
		return "ILIKE"
	case IN:
		return "IN"
	case NOT_IN:
		return "NOT IN"
	case IS_NULL:
		return "IS NULL"
	case IS_NOT_NULL:
		return "IS NOT NULL"
	default:
		return "?"
	}
}

// generateUnaryExpr 生成一元表达式
func (g *SQLGenerator) generateUnaryExpr(expr *UnaryExpr) string {
	operand := g.generateExpression(expr.Operand)
	switch expr.Operator {
	case NOT:
		return "NOT " + operand
	case MINUS_UNARY:
		return "-" + operand
	case PLUS_UNARY:
		return "+" + operand
	default:
		return operand
	}
}

// generateFunctionCall 生成函数调用
func (g *SQLGenerator) generateFunctionCall(fn *FunctionCall) string {
	result := fn.Name
	if fn.Distinct {
		result += "(DISTINCT "
	} else {
		result += "("
	}

	if len(fn.Args) > 0 {
		args := make([]string, len(fn.Args))
		for i, arg := range fn.Args {
			args[i] = g.generateExpression(arg)
		}
		result += strings.Join(args, ", ")
	}

	result += ")"

	// 窗口函数
	if fn.Over != nil {
		result += " OVER " + g.generateWindowSpec(fn.Over)
	}

	return result
}

// generateWindowSpec 生成窗口规范
func (g *SQLGenerator) generateWindowSpec(spec *WindowSpec) string {
	var parts []string

	// PARTITION BY
	if len(spec.PartitionBy) > 0 {
		partitionExprs := make([]string, len(spec.PartitionBy))
		for i, expr := range spec.PartitionBy {
			partitionExprs[i] = g.generateExpression(expr)
		}
		parts = append(parts, "PARTITION BY "+strings.Join(partitionExprs, ", "))
	}

	// ORDER BY
	if len(spec.OrderBy) > 0 {
		orderExprs := make([]string, len(spec.OrderBy))
		for i, expr := range spec.OrderBy {
			orderExprs[i] = g.generateOrderByExpr(&expr)
		}
		parts = append(parts, "ORDER BY "+strings.Join(orderExprs, ", "))
	}

	// FRAME
	if spec.Frame != nil {
		parts = append(parts, g.generateWindowFrame(spec.Frame))
	}

	return "(" + strings.Join(parts, " ") + ")"
}

// generateWindowFrame 生成窗口框架
func (g *SQLGenerator) generateWindowFrame(frame *WindowFrame) string {
	var frameType string
	switch frame.Type {
	case RowsFrame:
		frameType = "ROWS"
	case RangeFrame:
		frameType = "RANGE"
	}

	start := g.generateFrameBound(frame.Start)
	end := g.generateFrameBound(frame.End)

	if frame.End != nil {
		return fmt.Sprintf("%s BETWEEN %s AND %s", frameType, start, end)
	}
	return fmt.Sprintf("%s %s", frameType, start)
}

// generateFrameBound 生成框架边界
func (g *SQLGenerator) generateFrameBound(bound *FrameBound) string {
	if bound == nil {
		return "CURRENT ROW"
	}

	switch bound.Type {
	case UnboundedPreceding:
		return "UNBOUNDED PRECEDING"
	case CurrentRow:
		return "CURRENT ROW"
	case UnboundedFollowing:
		return "UNBOUNDED FOLLOWING"
	case Preceding:
		return g.generateExpression(bound.Offset) + " PRECEDING"
	case Following:
		return g.generateExpression(bound.Offset) + " FOLLOWING"
	default:
		return "CURRENT ROW"
	}
}

// generateOrderByExpr 生成ORDER BY表达式
func (g *SQLGenerator) generateOrderByExpr(expr *OrderByExpr) string {
	result := g.generateExpression(expr.Expr)

	switch expr.Direction {
	case ASC:
		result += " ASC"
	case DESC:
		result += " DESC"
	}

	switch expr.Nulls {
	case NullsFirst:
		result += " NULLS FIRST"
	case NullsLast:
		result += " NULLS LAST"
	}

	return result
}

// generateUpdateExpr 生成UPDATE表达式
func (g *SQLGenerator) generateUpdateExpr(expr *UpdateExpr) string {
	return expr.Column + " = " + g.generateExpression(expr.Value)
}

// generateJoinExpr 生成JOIN表达式
func (g *SQLGenerator) generateJoinExpr(join *JoinExpr) string {
	var joinType string
	switch join.Type {
	case InnerJoin:
		joinType = "INNER JOIN"
	case LeftJoin:
		joinType = "LEFT JOIN"
	case RightJoin:
		joinType = "RIGHT JOIN"
	case FullJoin:
		joinType = "FULL JOIN"
	case CrossJoin:
		joinType = "CROSS JOIN"
	}

	result := joinType + " " + g.generateTableRef(*join.Table)
	if join.Condition != nil {
		result += " ON " + g.generateExpression(join.Condition)
	}

	return result
}

// generateCaseExpr 生成CASE表达式
func (g *SQLGenerator) generateCaseExpr(expr *CaseExpr) string {
	result := "CASE"
	if expr.Expr != nil {
		result += " " + g.generateExpression(expr.Expr)
	}

	for _, when := range expr.WhenList {
		result += " WHEN " + g.generateExpression(when.Condition)
		result += " THEN " + g.generateExpression(when.Result)
	}

	if expr.Else != nil {
		result += " ELSE " + g.generateExpression(expr.Else)
	}

	result += " END"
	return result
}

// generateArrayExpr 生成数组表达式
func (g *SQLGenerator) generateArrayExpr(expr *ArrayExpr) string {
	elements := make([]string, len(expr.Elements))
	for i, elem := range expr.Elements {
		elements[i] = g.generateExpression(elem)
	}
	return "ARRAY[" + strings.Join(elements, ", ") + "]"
}

// generateArrayAccess 生成数组访问
func (g *SQLGenerator) generateArrayAccess(expr *ArrayAccess) string {
	return g.generateExpression(expr.Array) + "[" + g.generateExpression(expr.Index) + "]"
}

// generateJSONBExpr 生成JSONB表达式
func (g *SQLGenerator) generateJSONBExpr(expr *JSONBExpr) string {
	left := g.generateExpression(expr.Left)
	right := g.generateExpression(expr.Right)
	op := g.getJSONBOpString(expr.Operator)
	return fmt.Sprintf("(%s %s %s)", left, op, right)
}

// getJSONBOpString 获取JSONB操作符字符串
func (g *SQLGenerator) getJSONBOpString(op JSONBOp) string {
	switch op {
	case JSONBExtract:
		return "->"
	case JSONBExtractText:
		return "->>"
	case JSONBPath:
		return "#>"
	case JSONBPathText:
		return "#>>"
	case JSONBContains:
		return "@>"
	case JSONBContainedBy:
		return "<@"
	case JSONBExists:
		return "?"
	case JSONBExistsAny:
		return "?|"
	case JSONBExistsAll:
		return "?&"
	case JSONBConcat:
		return "||"
	case JSONBDelete:
		return "-"
	case JSONBDeletePath:
		return "#-"
	default:
		return "?"
	}
}

// generateColumnDef 生成列定义
func (g *SQLGenerator) generateColumnDef(col *ColumnDef) string {
	result := col.Name + " " + g.generateTypeName(col.Type)

	// 约束
	for _, constraint := range col.Constraints {
		result += " " + g.generateColumnConstraint(constraint)
	}

	// 默认值
	if col.Default != nil {
		result += " DEFAULT " + g.generateExpression(col.Default)
	}

	return result
}

// generateTypeName 生成类型名
func (g *SQLGenerator) generateTypeName(typeName *TypeName) string {
	result := typeName.Name

	// 类型参数
	if len(typeName.Size) > 0 {
		sizes := make([]string, len(typeName.Size))
		for i, size := range typeName.Size {
			sizes[i] = g.generateExpression(size)
		}
		result += "(" + strings.Join(sizes, ", ") + ")"
	}

	// 数组维度
	for i := 0; i < typeName.ArrayDims; i++ {
		result += "[]"
	}

	return result
}

// generateColumnConstraint 生成列约束
func (g *SQLGenerator) generateColumnConstraint(constraint *ColumnConstraint) string {
	switch constraint.Type {
	case NotNullConstraint:
		return "NOT NULL"
	case NullConstraint:
		return "NULL"
	case UniqueConstraint:
		return "UNIQUE"
	case PrimaryKeyConstraint:
		return "PRIMARY KEY"
	case CheckConstraint:
		return "CHECK (" + g.generateExpression(constraint.Check) + ")"
	case ForeignKeyConstraint:
		return "REFERENCES " + g.generateForeignKeyDef(constraint.References)
	default:
		return ""
	}
}

// generateForeignKeyDef 生成外键定义
func (g *SQLGenerator) generateForeignKeyDef(fk *ForeignKeyDef) string {
	result := g.generateTableRef(*fk.Table)
	if len(fk.Columns) > 0 {
		result += " (" + strings.Join(fk.Columns, ", ") + ")"
	}
	return result
}

// generateIndexColumn 生成索引列
func (g *SQLGenerator) generateIndexColumn(col *IndexColumn) string {
	result := g.generateExpression(col.Expr)

	switch col.Direction {
	case ASC:
		result += " ASC"
	case DESC:
		result += " DESC"
	}

	switch col.Nulls {
	case NullsFirst:
		result += " NULLS FIRST"
	case NullsLast:
		result += " NULLS LAST"
	}

	return result
}

// generateAlterTableAction 生成ALTER TABLE动作
func (g *SQLGenerator) generateAlterTableAction(action *AlterTableAction) string {
	switch action.Type {
	case AddColumn:
		return "ADD COLUMN " + g.generateColumnDef(action.Column)
	case DropColumn:
		dropClause := "DROP COLUMN"
		if action.IfExists {
			dropClause += " IF EXISTS"
		}
		return dropClause + " " + action.OldName
	case AlterColumn:
		return "ALTER COLUMN " + action.OldName + " TYPE " + g.generateTypeName(action.Column.Type)
	case AddConstraint:
		return "ADD " + g.generateTableConstraint(action.Constraint)
	case DropConstraint:
		dropClause := "DROP CONSTRAINT"
		if action.IfExists {
			dropClause += " IF EXISTS"
		}
		return dropClause + " " + action.OldName
	case RenameTable:
		return "RENAME TO " + action.NewName
	case RenameColumn:
		return "RENAME COLUMN " + action.OldName + " TO " + action.NewName
	default:
		return "/* Unsupported alter action */"
	}
}

// generateTableConstraint 生成表约束
func (g *SQLGenerator) generateTableConstraint(constraint *TableConstraint) string {
	var result string
	if constraint.Name != "" {
		result = "CONSTRAINT " + constraint.Name + " "
	}

	switch constraint.Type {
	case UniqueConstraint:
		result += "UNIQUE (" + strings.Join(constraint.Columns, ", ") + ")"
	case PrimaryKeyConstraint:
		result += "PRIMARY KEY (" + strings.Join(constraint.Columns, ", ") + ")"
	case CheckConstraint:
		result += "CHECK (" + g.generateExpression(constraint.Check) + ")"
	case ForeignKeyConstraint:
		result += "FOREIGN KEY (" + strings.Join(constraint.Columns, ", ") + ") REFERENCES " + g.generateForeignKeyDef(constraint.References)
	default:
		return "/* Unsupported constraint type */"
	}

	return result
}

// 新增表达式生成器方法
func (g *SQLGenerator) generateAggregateExpr(expr *AggregateExpr) string {
	result := expr.Name
	if expr.Distinct {
		result += "(DISTINCT "
	} else {
		result += "("
	}
	
	if len(expr.Args) > 0 {
		args := make([]string, len(expr.Args))
		for i, arg := range expr.Args {
			args[i] = g.generateExpression(arg)
		}
		result += strings.Join(args, ", ")
	}
	
	result += ")"
	
	if expr.Filter != nil {
		result += " FILTER (WHERE " + g.generateExpression(expr.Filter) + ")"
	}
	
	if expr.OrderBy != nil && len(expr.OrderBy) > 0 {
		orderExprs := make([]string, len(expr.OrderBy))
		for i, orderExpr := range expr.OrderBy {
			orderExprs[i] = g.generateOrderByExpr(&orderExpr)
		}
		result += " ORDER BY " + strings.Join(orderExprs, ", ")
	}
	
	return result
}

func (g *SQLGenerator) generateExistsExpr(expr *ExistsExpr) string {
	return "EXISTS (" + g.generateSelectStmt(expr.Subquery.Select) + ")"
}

func (g *SQLGenerator) generateInExpr(expr *InExpr) string {
	result := g.generateExpression(expr.Expr)
	if expr.Not {
		result += " NOT IN "
	} else {
		result += " IN "
	}
	
	if expr.Subquery != nil {
		result += "(" + g.generateSelectStmt(expr.Subquery.Select) + ")"
	} else if len(expr.List) > 0 {
		values := make([]string, len(expr.List))
		for i, val := range expr.List {
			values[i] = g.generateExpression(val)
		}
		result += "(" + strings.Join(values, ", ") + ")"
	}
	
	return result
}

func (g *SQLGenerator) generateBetweenExpr(expr *BetweenExpr) string {
	result := g.generateExpression(expr.Expr)
	if expr.Not {
		result += " NOT BETWEEN "
	} else {
		result += " BETWEEN "
	}
	result += g.generateExpression(expr.Lower) + " AND " + g.generateExpression(expr.Upper)
	return result
}

func (g *SQLGenerator) generateTypeCastExpr(expr *TypeCastExpr) string {
	return g.generateExpression(expr.Expr) + "::" + g.generateTypeName(expr.Type)
}

func (g *SQLGenerator) generateIsNullExpr(expr *IsNullExpr) string {
	result := g.generateExpression(expr.Expr)
	if expr.Not {
		result += " IS NOT NULL"
	} else {
		result += " IS NULL"
	}
	return result
}

func (g *SQLGenerator) generateLikeExpr(expr *LikeExpr) string {
	result := g.generateExpression(expr.Expr)
	if expr.Not {
		result += " NOT LIKE "
	} else {
		result += " LIKE "
	}
	result += g.generateExpression(expr.Pattern)
	if expr.Escape != nil {
		result += " ESCAPE " + g.generateExpression(expr.Escape)
	}
	return result
}

func (g *SQLGenerator) generateRowExpr(expr *RowExpr) string {
	if len(expr.Exprs) == 0 {
		return "ROW()"
	}
	
	exprs := make([]string, len(expr.Exprs))
	for i, e := range expr.Exprs {
		exprs[i] = g.generateExpression(e)
	}
	return "ROW(" + strings.Join(exprs, ", ") + ")"
}

func (g *SQLGenerator) generateArraySliceExpr(expr *ArraySliceExpr) string {
	result := g.generateExpression(expr.Array) + "["
	if expr.Lower != nil {
		result += g.generateExpression(expr.Lower)
	}
	result += ":"
	if expr.Upper != nil {
		result += g.generateExpression(expr.Upper)
	}
	result += "]"
	return result
}

func (g *SQLGenerator) generateCoalesceExpr(expr *CoalesceExpr) string {
	if len(expr.Exprs) == 0 {
		return "COALESCE()"
	}
	
	exprs := make([]string, len(expr.Exprs))
	for i, e := range expr.Exprs {
		exprs[i] = g.generateExpression(e)
	}
	return "COALESCE(" + strings.Join(exprs, ", ") + ")"
}

func (g *SQLGenerator) generateNullIfExpr(expr *NullIfExpr) string {
	return "NULLIF(" + g.generateExpression(expr.Expr1) + ", " + g.generateExpression(expr.Expr2) + ")"
}

func (g *SQLGenerator) generateGreatestExpr(expr *GreatestExpr) string {
	if len(expr.Exprs) == 0 {
		return "GREATEST()"
	}
	
	exprs := make([]string, len(expr.Exprs))
	for i, e := range expr.Exprs {
		exprs[i] = g.generateExpression(e)
	}
	return "GREATEST(" + strings.Join(exprs, ", ") + ")"
}

func (g *SQLGenerator) generateLeastExpr(expr *LeastExpr) string {
	if len(expr.Exprs) == 0 {
		return "LEAST()"
	}
	
	exprs := make([]string, len(expr.Exprs))
	for i, e := range expr.Exprs {
		exprs[i] = g.generateExpression(e)
	}
	return "LEAST(" + strings.Join(exprs, ", ") + ")"
}